home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-12-23 | 6.4 KB | 148 lines | [TEXT/EDIT] |
- ; Examples of the use of MacScheme's simple-minded reader
- ; customization procedures, readtable-ref and readtable-set!.
- ;
- ; The examples show how to make one character act like another,
- ; how to define non-terminating and terminating read-character-
- ; macros, and how to make #'x read as (function x) to aid in
- ; translating existing Lisp code into Scheme.
- ;
- ; Warning: To save space, MacScheme maintains a single global
- ; readtable. The readtable-set! procedure operates directly
- ; on this global readtable. If you make a mistake, you may
- ; find yourself with an unusable readtable.
- ;
- ; Another warning: Changes to the readtable do not affect the
- ; MacScheme user interface, so the Pick and Pick&Eval menu items
- ; may not work with the syntax you define. You may have to select
- ; an expression using the mouse and choose Eval from the Commands
- ; menu in order to evaluate expressions that use your new syntax.
-
- ; The following will make the [ and ] characters behave much like
- ; ( and ). The main difference is that "dotted" notation currently
- ; doesn't work if the ] character is the closing bracket.
-
- (readtable-set! #\[ (readtable-ref #\( ))
- (readtable-set! #\] (readtable-ref #\) ))
-
- ; The following will make the { and } characters behave like
- ; alphabetic characters.
-
- (readtable-set! #\{ (readtable-ref #\a))
- (readtable-set! #\} (readtable-ref #\a))
-
- ; A final warning: The data structures used by readtable-ref
- ; are insufficiently abstract and are hard to use, so they may
- ; be changed in a future version of MacScheme. If this happens,
- ; some of the code that appears below will have to be changed.
-
- ; A procedure for defining non-terminating read-macro-characters.
- ; The char argument specifies the macro character, and the proc
- ; argument is a procedure of two arguments that will be called
- ; when the macro character is scanned. The first argument to
- ; proc will be the macro character and the second argument will
- ; be the port being read. The macro character will already have
- ; been consumed from the port.
-
- (define define-macro-character
- (let ((typical-readtable-entry (readtable-ref #\a)))
- (lambda (char proc)
- (let ((readtable-entry (readtable-ref char)))
- (readtable-set! char
- (cons 0
- (cons proc
- (cddr typical-readtable-entry))))))))
-
- ; The following example defines ? to be a read-macro-character
- ; such that ?x reads as (? . x). Artificial intelligence researchers
- ; seem to like this.
-
- (define-macro-character #\?
- (lambda (c p)
- (cons '? (read p))))
-
- ; Sometimes a terminating read-macro-character is called for.
-
- (define define-terminating-macro-character
- (lambda (char proc)
- (define-macro-character char proc)
- (readtable-set! char (cons 2 (cdr (readtable-ref char))))))
-
- ; The following example mimics the vertical bar syntax used in many
- ; dialects of Lisp for the purpose of writing symbols whose print
- ; names contain special characters or characters in the non-standard
- ; case. It works only for input, and only when the entire symbol is
- ; enclosed within vertical bars.
-
- (define-terminating-macro-character #\|
- (lambda (c p)
- (do ((c (read-char p) (read-char p))
- (chars '() (cons c chars)))
- ((char=? c #\|)
- (string->symbol (list->string (reverse chars)))))))
-
- ; It isn't easy to define new # macro characters in MacScheme.
- ; The following example makes #'x read as (function x) by redefining
- ; the action of the # character. This might be part of a Common
- ; Lisp compatibility package for MacScheme. (A simple compatibility
- ; package can get away with defining function as a macro such
- ; that (function x) expands to x; in a more sophisticated package
- ; the function macro would translate Common Lisp into Scheme.)
-
- (let ((original-readtable-entry-for-# (readtable-ref #\#))
- (original-readtable-entry-for-' (readtable-ref #\')))
- (let ((syntax-category (car original-readtable-entry-for-#))
- (dispatcher (cadr original-readtable-entry-for-#))
- (list-dispatcher (caddr original-readtable-entry-for-#))
- (quote-list-dispatcher
- (caddr original-readtable-entry-for-')))
- (readtable-set! #\#
- (list syntax-category
- (lambda (c p)
- (let ((c2 (peek-char p)))
- (if (char=? c2 #\')
- (begin (read-char p)
- (list 'function (read p)))
- (dispatcher c p))))
- (lambda (c p)
- (let ((c2 (peek-char p)))
- (if (char=? c2 #\')
- (begin
- (read-char p)
- (let* ((c (read-char p))
- (x ((caddr (readtable-ref c)) c p)))
- (cons (list 'function (car x)) (cdr x))))
- (list-dispatcher c p))))))))
-
- ; This code changes the MacScheme readtable to support a
- ; #|...|# syntax for comments.
-
- (let ((original-readtable-entry-for-# (readtable-ref #\#)))
- (let ((syntax-category (car original-readtable-entry-for-#))
- (dispatcher (cadr original-readtable-entry-for-#))
- (list-dispatcher (caddr original-readtable-entry-for-#)))
- (define (flush-comment c p)
- (if (and (char=? c #\|)
- (char=? (peek-char p) #\#))
- (read-char p)
- (flush-comment (read-char p) p)))
- (readtable-set! #\#
- (list syntax-category
- (lambda (c p)
- (let ((c2 (peek-char p)))
- (if (char=? c2 #\|)
- (begin
- (read-char p)
- (flush-comment (read-char p) p)
- (read p))
- (dispatcher c p))))
- (lambda (c p)
- (let ((c2 (peek-char p)))
- (if (char=? c2 #\|)
- (begin
- (read-char p)
- (flush-comment (read-char p) p)
- (let ((c (read-char p)))
- ((caddr (readtable-ref c)) c p)))
- (list-dispatcher c p))))))))
-
-